#include "../include/soundplayer.h"
#include "../include/arg_parse.h"
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdint.h>
#include <unistd.h>
#include <dlfcn.h>

environment_t env;


void progress(uint32_t bytes_elapsed, uint32_t bytes_total) {
	env->message("%i of %i\r", bytes_elapsed, bytes_total);
	fflush(stdout);
}

void print_version(){
	env->message("soundplayer version %s\nwritten by timothy3592 and x0thatguy0x\n", VERSION);
}

void help(){
	env->message("Usage: %s [args] infile\n", "soundplayer");
	env->message("\tCommandline Options\n");
	env->message("\t\t-h\tdisplay this help\n");
	env->message("\t\t-r\tset sample rate\n");
	env->message("\t\t-c\tset number of channels(partially implemented)\n");
	env->message("\t\t-o\tchoose sound output: alsa or oss\n");
	env->message("\t\t-a\tchoose output audio device\n");
	env->message("\t\t-p\tuse some filters.\n");
	env->message("\t\t-f\tcodec selection\n");
	env->message("\t\t-d\tswitch between 8bit or 16bit\n");
	env->message("\t\t-V\tdisplay version information\n");
	env->message("\t\t-n\tdo not check for or parse an id3 tag\n");
	//env->message("\t\t-t\toverride max number of attempts before failure\n"); //i do no such checking
}


int arg_parse(int argc, char **argv) {
	 //variables
	env = new_soundplayer_environment();
	env->format = qualify_filename(argv[argc-1]); //very crude
	env->progress = &progress;
	void* plugin_handle = NULL; //this can be left as-is if we don't use plugins

	//parse command line options
	int parse;
	while ( (parse = getopt(argc, argv, "hVnqr:o:c:d:t:f:a:p:") ) != -1){
		switch (parse){
		case 'h':
			help();
			return 1;
		case 'V':
			print_version();
			return 1;
		case 'n':
			env->noid3 = 1;
			break;
		case 'q':
			env->progress = sp_progress_default; //don't output anything
			break;
		case 'r':
			SET_OVERRIDE(SP_OVERRIDE_HERTZ);
			if (atoi(optarg) >= 8000 && atoi(optarg) <= 48000) env->rate = atoi(optarg);
			else env->message("selected sampling rate of %i is out of range\n", atoi(optarg) );
			break;
		case 'o':
			if (cmp("alsa", optarg) == 0) env->audio_out = 0;
			else if (cmp("oss", optarg) == 0) env->audio_out = 1;
			else {
				env->audio_out = -1;
				env->filename = optarg; //filename is a const char *
			}
			break;
		case 'c':
			SET_OVERRIDE(SP_OVERRIDE_CHANNEL);
			env->channels = atoi(optarg);
			break;
		case 'd':
			if (atoi(optarg) == 8 || atoi(optarg) == 16){
				if (atoi(optarg) == 8) env->bit_depth_alsa = 1;   /*SND_PCM_FORMAT_U8 == 1*/
				else if (atoi(optarg) == 16) env->bit_depth_alsa = 2;   /*SND_PCM_FORMAT_S16_LE == 2 in the enum*/
				env->bit_depth = atoi(optarg);
			}
			else env->message("Invalid sample size %i selected, keeping default (16 bit)\n", atoi(optarg));
			break;
		case 't':
			env->retry_threshold = atoi(optarg);
			break;
		case 'f':
			SET_OVERRIDE(SP_OVERRIDE_FORMAT); //set the format override flag
			if      (cmp("wav", optarg)== 0) env->format = TYPE_WAVE;
			else if (cmp("mp3", optarg)== 0) env->format = TYPE_MP3;
			else if (cmp("ogg", optarg)== 0) env->format = TYPE_OGG;
			else if (cmp("aac", optarg)== 0) env->format = TYPE_AAC;
			else if (cmp("flac", optarg)== 0) env->format = TYPE_FLAC;
			else {
				env->message("Attempted to force an invalid codec.\nUsing MP3 instead.\n");
				env->format = 10;
			}
			break;
		case 'a':
			env->audio_device = optarg;
			break;
		case 'p':
			//p for postprocessing... I'm struggling for letters here sinced i've used f
			//i'll have to switch to long options later
			sp_set_use_filter(1);
			plugin_handle = dlopen("libspfilter.so", RTLD_NOW);
			if (plugin_handle == NULL) env->message("plugin library not found\n");
			env->filter = dlsym(plugin_handle, optarg);
			if (env->filter == NULL) env->message("requested filter not found in library\n");
			break;
		}
	}
   return 0;
}
